/*
Chris Elrod
10/27/2008
CSci 252
Prof. Hasan

Project 2 - EJB

Reference: 
    BEA trader example: BEA 10.3 HOME\wlserver_10.3\samples\server\examples\src\examples\ejb\ejb20\basic\statefulSession
*/

package examples.ejb.ejb20.basic.Project2;

import javax.ejb.CreateException;
import javax.ejb.RemoveException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.rmi.RemoteException;
import javax.rmi.PortableRemoteObject;
import weblogic.ejbgen.*;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.*;
import java.util.Hashtable;
import java.util.Vector;


/**
 * FacadeBean is a stateful Session Bean. This bean illustrates:
 * 
 * Automatic persistence of state between calls to the Session Bean.
 * Looking up values from the Environment.
 * 
 */


@FileGeneration(remoteClass = Constants.Bool.TRUE,
                localHome = Constants.Bool.FALSE,
                remoteHome = Constants.Bool.TRUE,
                remoteClassName = "Facade",
                remoteHomeName = "FacadeHome",
                localClass = Constants.Bool.FALSE)
@JarSettings(ejbClientJar = "Project2_client.jar")
@JndiName(remote = "Project2-Facade-FacadeHome")
@Session(idleTimeoutSeconds = "600",
         maxBeansInCache = "1000",
         transTimeoutSeconds = "0",
         type = Session.SessionType.STATEFUL,
         defaultTransaction = Constants.TransactionAttribute.REQUIRED,
         ejbName = "statefulSession_Facade",
         enableCallByReference = Constants.Bool.TRUE)


public class FacadeBean implements SessionBean {


  private SessionContext ctx;
  private Hashtable table = new Hashtable();

  private String url;

  private static final String JNDI_NAME_Security = "Project2-Security-SecurityHome";
  private SecurityHome security_home;
  private Security security;

  private static final String JNDI_NAME_Profile = "Project2-Profile-ProfileHome";
  private ProfileHome profile_home;
  private Profile profile;

  private static final String JNDI_NAME_Transaction = "Project2-Transaction-TransactionHome";
  private TransactionHome transaction_home;
  private Transaction transaction;
  

  public FacadeBean() throws NamingException, CreateException, RemoteException, RemoveException{
    this.url = "t3://localhost:7001";

    this.security_home = lookupSecurityHome();
    this.security = (Security) narrow(security_home.create(), Security.class);   

    this.profile_home = lookupProfileHome();
    this.profile = (Profile) narrow(profile_home.create(), Profile.class);   

    this.transaction_home = lookupTransactionHome();
    this.transaction = (Transaction) narrow(transaction_home.create(), Transaction.class);   
  }


  private void log(String s) {
    System.out.println(s);
  } 

  
  /**
   * This method is required by the EJB Specification,
   * but is not used by this example.
   */
  public void ejbActivate() {
    log("ejbActivate called");
  }


  /**
   * This method is required by the EJB Specification,
   * but is not used by this example.
   */
  public void ejbRemove() {
    log("ejbRemove called");
  }


  /**
   * This method is required by the EJB Specification,
   * but is not used by this example.
   */
  public void ejbPassivate() {
    log("ejbPassivate called");
  }


  /**
   * 
   * This method is required by the EJB Specification,
   * but is not used by this example.
   *
   * Sets the session context.
   *
   * @param ctx SessionContext Context for session
   */
  public void setSessionContext(SessionContext ctx) {
    log("setSessionContext called");
    this.ctx = ctx;
  }


  /**
   * This method corresponds to the create method in the home interface
   * "FacadeHome.java".
   * The parameter sets of the two methods are identical. When the client calls
   * FacadeHome.create(), the container allocates an instance of 
   * the EJBean and calls ejbCreate().
   *
   * @exception               javax.ejb.CreateException
   *                          if there is a problem creating the bean
   * @see                     examples.ejb.ejb20.basic.Project2.Facade
   */
  public void ejbCreate () throws CreateException {
    log("ejbCreate called");

    try {
      InitialContext ic = new InitialContext();
    } catch (NamingException ne) {
      throw new CreateException("Failed to find environment value "+ne);
    }
  }


  /*Validates user id and password, via call to Security's createUser(uid, password).
    Parameters are user id and password.  Returns true based on success of Security's
    createUser(uid, password).
    Parms: Strings user_id and password. Returns a boolean.*/
  @RemoteMethod()
  
  public boolean createUser(String uid, String password) throws RemoteException{   
    return security.createUser(uid, password);
  }


  /*Returns an address based on match between the agrument uid and the address.txt file.
    Parms: Strins user_id and password.  Returns a boolean.*/ 
  @RemoteMethod()
  
  public boolean authenticate(String uid, String password) throws RemoteException{   
    return security.authenticate(uid, password); 
  }


/*Validates user id and password, then does a write to password.txt.
  Parms: Strings user_id and password. Returns a boolean*/
  @RemoteMethod()
  
  public boolean addProfile (String uid, String address) throws RemoteException{  
    return profile.addProfile(uid, address);
  }



/*Returns an address based on match between the agrument uid and the address.txt file.
  Parms: Strings user_id. Returns a boolean*/
  @RemoteMethod()
  
  public String getAddress(String uid) throws RemoteException{  
    return profile.getAddress( uid ); 
  }


  /*Adds a request.
  Parms: Strings requestinfo. Returns a boolean*/ 
  @RemoteMethod()

  public boolean addRequest (String requestinfo) throws RemoteException{
    
    return transaction.addRequest(requestinfo);
  }


  /*Approves a transaction.
  Parms: Strings user_id. Returns a boolean*/ 
  @RemoteMethod()

  public boolean approveTransaction(String id) throws RemoteException, CreateException, RemoveException {
    
    return transaction.approveTransaction(id);
  }  


  /*Rejects a transaction.
  Parms: Strings user_id. Returns a boolean*/ 
  @RemoteMethod()

  public boolean rejectTransaction(String id) throws RemoteException, CreateException, RemoveException {
    
    return transaction.rejectTransaction(id);
  }  

  
  /*Gets the ids.
  Returns a Vector*/
  @RemoteMethod()

  public Vector getIds() throws RemoteException{  
    return transaction.getIds(); 
  }


  /*Gets a request's title.*/ 
  @RemoteMethod()

  public String getTitle (int position) throws RemoteException {  

    return transaction.getTitle(position);  
  }


  /*Gets a request's ISBN.*/ 
  @RemoteMethod()

  public String getISBN (String title) throws RemoteException{  

    return transaction.getISBN( title );  
  }


  /*Gets a request's quantity.*/ 
  @RemoteMethod()

  public int getQuantity (int position) throws RemoteException{  

    return transaction.getQuantity(position);  
  } 


  /*Gets a request's name.*/ 
  @RemoteMethod()

  public String getName (int position) throws RemoteException{  

    return transaction.getName(position);
  } 


  /*Gets a request's address.*/ 
  @RemoteMethod()

  public String getAddress (int position) throws RemoteException{  

    return transaction.getAddress(position);  
  } 


  /*Gets a request's organization.*/ 
  @RemoteMethod()

  public String getOrganization (int position) throws RemoteException{  

    return transaction.getOrganization(position);  
  }


  /**
   * Lookup the EJBs home in the JNDI tree
   */
  private SecurityHome lookupSecurityHome() throws NamingException {
    // Lookup the beans home using JNDI
    Context ctx = getInitialContext();

    try {
      Object home = ctx.lookup(JNDI_NAME_Security);
      return (SecurityHome) narrow(home, SecurityHome.class);
    } catch (NamingException ne) {
      log("The client was unable to lookup the EJBHome.  Please make sure ");
      log("that you have deployed the ejb with the JNDI name "+
        JNDI_NAME_Security + " on the WebLogic server at "+url);
      throw ne;
    }
  }


  /**
   * Lookup the EJBs home in the JNDI tree
   */
  private ProfileHome lookupProfileHome() throws NamingException {
    // Lookup the beans home using JNDI
    Context ctx = getInitialContext();

    try {
      Object home = ctx.lookup(JNDI_NAME_Profile);
      return (ProfileHome) narrow(home, ProfileHome.class);
    } catch (NamingException ne) {
      log("The client was unable to lookup the EJBHome.  Please make sure ");
      log("that you have deployed the ejb with the JNDI name "+
        JNDI_NAME_Profile + " on the WebLogic server at "+url);
      throw ne;
    }
  }


  /**
   * Lookup the EJBs home in the JNDI tree
   */
  private TransactionHome lookupTransactionHome() throws NamingException {
    // Lookup the beans home using JNDI
    Context ctx = getInitialContext();

    try {
      Object home = ctx.lookup(JNDI_NAME_Transaction);
      return (TransactionHome) narrow(home, TransactionHome.class);
    } catch (NamingException ne) {
      log("The client was unable to lookup the EJBHome.  Please make sure ");
      log("that you have deployed the ejb with the JNDI name "+
        JNDI_NAME_Transaction + " on the WebLogic server at "+url);
      throw ne;
    }
  }


  /**
   * RMI/IIOP clients should use this narrow function
   */
  private Object narrow(Object ref, Class c) {
    return PortableRemoteObject.narrow(ref, c);
  }


  /**
   * Using a Properties object will work on JDK 1.1.x and Java2
   * clients
   */
  private Context getInitialContext() throws NamingException {
    
    try {
      // Get an InitialContext
      Hashtable<String,String> h = new Hashtable<String,String>();
      h.put(Context.INITIAL_CONTEXT_FACTORY,
        "weblogic.jndi.WLInitialContextFactory");
      h.put(Context.PROVIDER_URL, url);
      return new InitialContext(h);
    } catch (NamingException ne) {
      log("We were unable to get a connection to the WebLogic server at "+url);
      log("Please make sure that the server is running.");
      throw ne;
    }
  }


}








